package life.sweet.community.service;

import life.sweet.community.dto.PaginationDTO;
import life.sweet.community.dto.QueryQuestionDTO;
import life.sweet.community.dto.QuestionDTO;
import life.sweet.community.exception.CustomException;
import life.sweet.community.exception.CustomErrorCode;
import life.sweet.community.mapper.QuestionExtMapper;
import life.sweet.community.mapper.QuestionMapper;
import life.sweet.community.mapper.UserMapper;
import life.sweet.community.model.Question;
import life.sweet.community.model.QuestionExample;
import life.sweet.community.model.User;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class QuestionService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private QuestionMapper questionMapper;
    @Autowired
    private QuestionExtMapper questionExtMapper;

    public PaginationDTO queryList(Integer page,Integer size,String search) {
        if(StringUtils.isNotBlank(search)) {
            search = search.replaceAll("[\\pP+~$`^=|<>～｀＄＾＋＝｜＜＞￥×]", ""); // 暂时规避所有标点符号
            if(StringUtils.isBlank(search)) {
                return new PaginationDTO();
            }
            String[] tagArr = StringUtils.split(search," ");
            search = Arrays.stream(tagArr).collect(Collectors.joining("|"));
        }
        QueryQuestionDTO queryQuestionDTO = new QueryQuestionDTO();
        queryQuestionDTO.setSearch(search);
        Integer totalCount = questionExtMapper.countBySearch(queryQuestionDTO);
        if(totalCount == 0) {
            return new PaginationDTO();
        }
        Integer totalPage;
        if(totalCount % size == 0) {
            totalPage =  totalCount / size;
        } else {
            totalPage = totalCount / size + 1;
        }
        if(page < 1) {
            page = 1;
        }
        if(page > totalPage) {
            page = totalPage;
        }
        PaginationDTO<QuestionDTO> paginationDTO = new PaginationDTO();
        paginationDTO.setPagination(totalPage,page,size);
        Integer offset = size * (page -1);
        /* QuestionExample questionExampleWithPage = new QuestionExample();
        questionExampleWithPage.setOrderByClause("gmt_create desc");
        RowBounds rowBound = new RowBounds(offset,size);
        List<Question> list = questionMapper.selectByExampleWithBLOBsWithRowbounds(questionExampleWithPage,rowBound); */
        queryQuestionDTO.setPage(offset);
        queryQuestionDTO.setSize(size);
        List<Question> list = questionExtMapper.selectBySearch(queryQuestionDTO);
        List<QuestionDTO> dtoList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(list)){
            for (Question question : list) {
                User user = userMapper.selectByPrimaryKey(question.getCreator());
                QuestionDTO dto  = new QuestionDTO();
                BeanUtils.copyProperties(question,dto);
                dto.setUser(user);
                dtoList.add(dto);
            }
        }
        paginationDTO.setData(dtoList);
        return paginationDTO;
    }

    public PaginationDTO listByUserId(Long userId, int page, int size) {
        PaginationDTO paginationDTO = new PaginationDTO();
        QuestionExample questionExample = new QuestionExample();
        questionExample.createCriteria().andCreatorEqualTo(userId);
        Integer totalCount = (int)questionMapper.countByExample(questionExample);
        if(totalCount == 0) {
            return new PaginationDTO();
        }
        Integer totalPage;

        if(totalCount % size == 0) {
            totalPage =  totalCount / size;
        } else {
            totalPage = totalCount / size + 1;
        }

        if(page < 1) {
            page = 1;
        }

        if(page > totalPage) {
            page = totalPage;
        }

        paginationDTO.setPagination(totalPage,page,size);
        Integer offset = size * (page -1);
        QuestionExample questionExampleWithPage = new QuestionExample();
        questionExampleWithPage.setOrderByClause("gmt_create desc");
        questionExampleWithPage.createCriteria().andCreatorEqualTo(userId);
        RowBounds rowBound = new RowBounds(offset,size);
        List<Question> list = questionMapper.selectByExampleWithBLOBsWithRowbounds(questionExampleWithPage,rowBound);
        List<QuestionDTO> dtoList = new ArrayList<>();
        if(!list.isEmpty()) {
            for (Question question : list) {
                User user = userMapper.selectByPrimaryKey(question.getCreator());
                QuestionDTO dto  = new QuestionDTO();
                BeanUtils.copyProperties(question,dto);
                dto.setUser(user);
                dtoList.add(dto);
            }
        }
        paginationDTO.setData(dtoList);
        return paginationDTO;
    }

    public QuestionDTO getById(Long id) {
        Question question = questionMapper.selectByPrimaryKey(id);
        if(question == null) {
            throw new CustomException(CustomErrorCode.QUESTION_NOT_FOUND);
        }
        QuestionDTO dto  = new QuestionDTO();
        BeanUtils.copyProperties(question,dto);
        // 用户信息
        User user = userMapper.selectByPrimaryKey(question.getCreator());
        dto.setUser(user);
        return dto;
    }


    public void insertOrUpdate(Question question) {
        question.setGmtModified(System.currentTimeMillis());
        if(question.getId() == null){
            question.setGmtCreate(System.currentTimeMillis());
            question.setViewCount(0);
            question.setCommentCount(0);
            question.setLikeCount(0);
            questionMapper.insert(question);
        } else {
            Question updateQuestion = new Question();
            BeanUtils.copyProperties(question,updateQuestion);
            QuestionExample questionExample = new QuestionExample();
            questionExample.createCriteria().andIdEqualTo(question.getId());
            int updated = questionMapper.updateByExampleSelective(updateQuestion,questionExample);
            if(updated != 1) {
                throw new CustomException(CustomErrorCode.QUESTION_NOT_FOUND);
            }
        }
    }

    public void incView(Long id) {
        Question question = new Question();
        question.setId(id);
        question.setViewCount(1); //自增1（防止多线程造成错误）
        questionExtMapper.incView(question);
    }

    public List<QuestionDTO> selectReleated(QuestionDTO questionDTO) {
        if(StringUtils.isBlank(questionDTO.getTag())) {
            return new ArrayList<>();
        }
        String[] tagArr = StringUtils.split(questionDTO.getTag(),",");
        String regexpTags = Arrays.stream(tagArr).collect(Collectors.joining("|"));
        Question question = new Question();
        question.setId(questionDTO.getId());
        question.setTag(regexpTags);
        List<Question> releatedQuestions = questionExtMapper.selectReleated(question);
        List<QuestionDTO> questionDtos = releatedQuestions.stream().map(q -> {
            QuestionDTO dto = new QuestionDTO();
            BeanUtils.copyProperties(q, dto);
            return dto;
        }).collect(Collectors.toList());
        return questionDtos;
    }
}
